# -*- coding: utf-8 -*-
# Copyright © 2024 weidongkl <weidongkx@gmail.com>
import logging
import os
import re
from excavator.exceptions import GrubBootError
from excavator.utils.shell import c_run_cmd
from excavator.utils.output import ExcavatorJobOutput
from excavator.job.base import Job
from excavator.models.report import notify_err, notify_info
from excavator.group import BootGroup
from excavator.models.pkg import DnfUpgrade
from excavator.models.efi import EfiInfoModel

logger = logging.getLogger("excavator.job")


class BootGrub(Job):
    group = BootGroup
    requires = (DnfUpgrade,)
    provides = ()

    def run(self, *args, **kwargs):
        ExcavatorJobOutput.info(self.name, "config grub")
        logger.info("config grub")
        obj = EfiInfoModel.get()
        if not obj.is_efi:
            logger.info("update grub bootloader on bios systems")
            cmd = "/usr/sbin/grub2-mkconfig -o  /etc/grub2.cfg"
            rc, out = c_run_cmd(cmd)
            if rc != 0:
                logger.error("grub2 config file generation failed.")
            try:
                device = self.get_boot_device()
                cmd = "/usr/sbin/grub2-install {}".format(device)
                rc, out = c_run_cmd(cmd)
                if rc != 0:
                    logger.error("grub2-install failed.")
            except Exception as e:
                logger.error(e)
        logger.info("config grub args")
        cmd = "/usr/sbin/grubby --update-kernel=/boot/{} --args=\" rhgb quiet\"".format(self.get_last_boot_kernel())
        ret, out = c_run_cmd(cmd)
        if ret != 0:
            msg = "update grub args failed : {}".format(out)
            logger.error(msg)
            notify_err(msg, self.name)
            return
        notify_info("update grub args success", self.name)

    @staticmethod
    def get_last_boot_kernel():
        logger.info("get boot kernel list")
        kernel_list = []
        for f in os.listdir("/boot"):
            if os.path.isfile(os.path.join("/boot", f)):
                if re.match("vmlinuz-(\d+\.){2}.+", f):
                    kernel_list.append(f)
        kernel_list.sort()
        logger.info(kernel_list)
        return kernel_list[-1]

    @staticmethod
    def get_boot_device():
        logger.info("get boot device")
        cmd = "/usr/sbin/grub2-probe --target=device /boot"
        rc,out=c_run_cmd(cmd)
        if rc !=0:
            raise GrubBootError()
        boot_device = out.strip()
        cmd = "/usr/bin/lsblk -spnlo name {}".format(boot_device)
        rc, out = c_run_cmd(cmd)
        if rc != 0:
            raise GrubBootError()
        return out.strip().splitlines()[-1].strip()
